import { http } from "@/utils/http";

/** 统一响应格式 */
export interface ApiResponse<T = any> {
  /** 状态码 */
  code: number;
  /** 响应消息 */
  message: string;
  /** 响应数据 */
  data?: T;
  /** 时间戳 */
  timestamp?: number;
}

// ==================== 公告级别和类型枚举 ====================

/** 公告级别枚举 */
export enum AnnouncementLevel {
  /** 普通 */
  NORMAL = 1,
  /** 重要 */
  IMPORTANT = 2,
  /** 紧急 */
  URGENT = 3
}

/** 公告类型枚举 */
export enum AnnouncementType {
  /** 系统公告 */
  SYSTEM = 1,
  /** 活动公告 */
  ACTIVITY = 2,
  /** 维护公告 */
  MAINTENANCE = 3,
  /** 其他 */
  OTHER = 4
}

/** 阅读状态枚举 */
export enum ReadStatus {
  /** 未读 */
  UNREAD = 0,
  /** 已读 */
  READ = 1,
  /** 已忽略 */
  IGNORED = 2
}

// ==================== 数据类型定义 ====================

/** 公告信息对象 */
export interface AnnouncementInfo {
  /** 公告ID */
  id: number;
  /** 公告标题 */
  title: string;
  /** 公告内容 */
  content: string;
  /** 公告类型 1-系统公告 2-活动公告 3-维护公告 4-其他 */
  type: number;
  /** 公告类型名称 */
  typeName: string;
  /** 公告级别 1-普通 2-重要 3-紧急 */
  level: number;
  /** 公告级别名称 */
  levelName: string;
  /** 状态 1-已发布 */
  status: number;
  /** 状态名称 */
  statusName: string;
  /** 是否置顶 0-否 1-是 */
  isTop: number;
  /** 是否弹窗 0-否 1-是 */
  isPopup: number;
  /** 目标受众 */
  targetAudience: string;
  /** 目标受众名称 */
  targetAudienceName: string;
  /** 发布时间 */
  publishTime: string;
  /** 过期时间 */
  expireTime: string;
  /** 浏览量 */
  viewCount: number;
  /** 是否已读 */
  read: boolean;
  /** 创建时间 */
  createTime: string;
  /** 更新时间 */
  updateTime: string;
}

/** 公告详情信息对象 */
export interface AnnouncementDetailInfo extends AnnouncementInfo {
  /** 创建人ID */
  creatorId: number;
  /** 创建人名称 */
  creatorName: string;
}

/** 消息中心公告信息对象 */
export interface MessageCenterAnnouncementInfo extends AnnouncementInfo {
  /** 阅读状态 null-未读 1-已读 2-已忽略 */
  readStatus: number | null;
  /** 阅读状态名称 */
  readStatusName: string;
  /** 阅读时间 */
  readTime: string | null;
  /** 是否已忽略 */
  ignored: boolean;
}

/** 分页响应对象 */
export interface PageResponse<T> {
  /** 记录列表 */
  records: T[];
  /** 总记录数 */
  total: number;
  /** 每页大小 */
  size: number;
  /** 当前页码 */
  current: number;
  /** 总页数 */
  pages: number;
}

// ==================== 请求参数类型 ====================

/** 获取有效公告列表请求参数 */
export interface GetAnnouncementListParams {
  /** 页码，默认1 */
  current?: number;
  /** 每页大小，默认10 */
  size?: number;
  /** 公告类型 1-系统公告 2-活动公告 3-维护公告 4-其他 */
  type?: number;
  /** 公告级别 1-普通 2-重要 3-紧急 */
  level?: number;
  /** 公告标题（模糊查询） */
  title?: string;
}

/** 获取用户消息中心公告列表请求参数 */
export interface GetMessageCenterAnnouncementsParams {
  /** 页码，默认1 */
  current?: number;
  /** 每页大小，默认10 */
  size?: number;
  /** 公告类型 1-系统公告 2-活动公告 3-维护公告 4-其他 */
  type?: number;
  /** 公告级别 1-普通 2-重要 3-紧急 */
  level?: number;
  /** 阅读状态 0-未读 1-已读 2-已忽略 */
  readStatus?: number;
  /** 只查询未读 true/false */
  onlyUnread?: boolean;
  /** 只查询已读 true/false */
  onlyRead?: boolean;
  /** 只查询已忽略 true/false */
  onlyIgnored?: boolean;
}

// ==================== API接口函数 ====================

/**
 * 获取有效公告列表
 * 获取所有有效的公告列表，支持分页和筛选
 * @param params 查询参数
 */
export const getAnnouncementListApi = (params?: GetAnnouncementListParams) => {
  return http.request<ApiResponse<PageResponse<AnnouncementInfo>>>(
    "get",
    "/api/announcements/list",
    {
      params
    }
  );
};

/**
 * 获取公告详情
 * 获取指定公告的详细信息
 * @param announcementId 公告ID
 */
export const getAnnouncementDetailApi = (announcementId: number) => {
  return http.request<ApiResponse<AnnouncementDetailInfo>>(
    "get",
    `/api/announcements/${announcementId}`
  );
};

/**
 * 获取置顶公告列表
 * 获取所有置顶公告，按优先级排序（紧急 > 重要 > 普通），同级别按发布时间倒序
 */
export const getTopAnnouncementsApi = () => {
  return http.request<ApiResponse<AnnouncementInfo[]>>(
    "get",
    "/api/announcements/top"
  );
};

/**
 * 获取弹窗公告列表（需登录）
 * 只返回用户未读且未忽略的弹窗公告
 */
export const getPopupAnnouncementsApi = () => {
  return http.request<ApiResponse<AnnouncementInfo[]>>(
    "get",
    "/api/announcements/popup"
  );
};

/**
 * 标记公告为已读（需登录）
 * 将指定公告标记为已读状态
 * @param announcementId 公告ID
 */
export const markAnnouncementAsReadApi = (announcementId: number) => {
  return http.request<ApiResponse<null>>(
    "post",
    `/api/announcements/${announcementId}/read`
  );
};

/**
 * 标记所有公告为已读（需登录）
 * 将所有未读公告标记为已读状态
 */
export const markAllAnnouncementsAsReadApi = () => {
  return http.request<ApiResponse<null>>("post", "/api/announcements/read-all");
};

/**
 * @deprecated 已废弃,请使用统一的 /api/notifications/stats 接口获取公告未读数
 * 获取未读公告数量(需登录)
 * 获取当前用户的未读公告数量
 */
export const getUnreadAnnouncementCountApi = () => {
  return http.request<ApiResponse<number>>(
    "get",
    "/api/announcements/unread-count"
  );
};

/**
 * 忽略公告（需登录）
 * 忽略后，该公告不再出现在弹窗列表中，但可在消息中心查看
 * @param announcementId 公告ID
 */
export const ignoreAnnouncementApi = (announcementId: number) => {
  return http.request<ApiResponse<null>>(
    "post",
    `/api/announcements/${announcementId}/ignore`
  );
};

/**
 * 取消忽略公告（需登录）
 * 取消忽略后，公告将恢复正常显示
 * @param announcementId 公告ID
 */
export const unignoreAnnouncementApi = (announcementId: number) => {
  return http.request<ApiResponse<null>>(
    "delete",
    `/api/announcements/${announcementId}/ignore`
  );
};

/**
 * 获取用户消息中心公告列表（需登录）
 * 获取当前用户的所有公告，支持筛选和分页
 * @param params 查询参数
 */
export const getMessageCenterAnnouncementsApi = (
  params?: GetMessageCenterAnnouncementsParams
) => {
  return http.request<ApiResponse<PageResponse<MessageCenterAnnouncementInfo>>>(
    "get",
    "/api/announcements/messages",
    {
      params
    }
  );
};

// ==================== 工具类 ====================

/** 用户公告工具类 */
export class UserAnnouncementUtils {
  /** 公告级别配置 */
  static readonly LevelConfig = {
    [AnnouncementLevel.NORMAL]: {
      label: "普通",
      color: "#909399",
      tagType: "info" as const
    },
    [AnnouncementLevel.IMPORTANT]: {
      label: "重要",
      color: "#E6A23C",
      tagType: "warning" as const
    },
    [AnnouncementLevel.URGENT]: {
      label: "紧急",
      color: "#F56C6C",
      tagType: "danger" as const
    }
  };

  /** 公告类型配置 */
  static readonly TypeConfig = {
    [AnnouncementType.SYSTEM]: {
      label: "系统公告",
      icon: "Bell",
      color: "#409EFF",
      tagType: "primary" as const
    },
    [AnnouncementType.ACTIVITY]: {
      label: "活动公告",
      icon: "Star",
      color: "#67C23A",
      tagType: "success" as const
    },
    [AnnouncementType.MAINTENANCE]: {
      label: "维护公告",
      icon: "Tools",
      color: "#E6A23C",
      tagType: "warning" as const
    },
    [AnnouncementType.OTHER]: {
      label: "其他",
      icon: "InfoFilled",
      color: "#909399",
      tagType: "info" as const
    }
  };

  /** 阅读状态配置 */
  static readonly ReadStatusConfig = {
    [ReadStatus.UNREAD]: {
      label: "未读",
      color: "#F56C6C",
      tagType: "danger" as const
    },
    [ReadStatus.READ]: {
      label: "已读",
      color: "#909399",
      tagType: "info" as const
    },
    [ReadStatus.IGNORED]: {
      label: "已忽略",
      color: "#C0C4CC",
      tagType: "info" as const
    }
  };

  /**
   * 获取公告级别信息
   * @param level 级别值
   */
  static getLevelInfo(level: number) {
    return (
      this.LevelConfig[level as AnnouncementLevel] ||
      this.LevelConfig[AnnouncementLevel.NORMAL]
    );
  }

  /**
   * 获取公告类型信息
   * @param type 类型值
   */
  static getTypeInfo(type: number) {
    return (
      this.TypeConfig[type as AnnouncementType] ||
      this.TypeConfig[AnnouncementType.OTHER]
    );
  }

  /**
   * 获取阅读状态信息
   * @param status 状态值（null表示未读）
   */
  static getReadStatusInfo(status: number | null) {
    if (status === null) {
      return this.ReadStatusConfig[ReadStatus.UNREAD];
    }
    return (
      this.ReadStatusConfig[status as ReadStatus] ||
      this.ReadStatusConfig[ReadStatus.UNREAD]
    );
  }

  /**
   * 格式化时间显示
   * @param time 时间字符串
   */
  static formatTime(time: string): string {
    if (!time) return "-";
    const date = new Date(time);
    const now = new Date();
    const diff = now.getTime() - date.getTime();

    const minute = 60 * 1000;
    const hour = 60 * minute;
    const day = 24 * hour;
    const month = 30 * day;

    if (diff < minute) {
      return "刚刚";
    } else if (diff < hour) {
      return Math.floor(diff / minute) + "分钟前";
    } else if (diff < day) {
      return Math.floor(diff / hour) + "小时前";
    } else if (diff < month) {
      return Math.floor(diff / day) + "天前";
    } else {
      return date.toLocaleDateString();
    }
  }

  /**
   * 格式化完整时间
   * @param time 时间字符串
   */
  static formatFullTime(time: string): string {
    if (!time) return "-";
    const date = new Date(time);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    const hours = String(date.getHours()).padStart(2, "0");
    const minutes = String(date.getMinutes()).padStart(2, "0");
    const seconds = String(date.getSeconds()).padStart(2, "0");
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  }

  /**
   * 判断公告是否已过期
   * @param expireTime 过期时间
   */
  static isExpired(expireTime: string): boolean {
    if (!expireTime) return false;
    return new Date(expireTime).getTime() < Date.now();
  }

  /**
   * 判断公告是否即将过期（24小时内）
   * @param expireTime 过期时间
   */
  static isExpiringSoon(expireTime: string): boolean {
    if (!expireTime) return false;
    const expireDate = new Date(expireTime).getTime();
    const now = Date.now();
    const diff = expireDate - now;
    const day = 24 * 60 * 60 * 1000;
    return diff > 0 && diff <= day;
  }

  /**
   * 格式化数字显示
   * @param num 数字
   */
  static formatNumber(num: number): string {
    if (num >= 10000) {
      return (num / 10000).toFixed(1) + "万";
    } else if (num >= 1000) {
      return (num / 1000).toFixed(1) + "k";
    }
    return num.toString();
  }

  /**
   * 处理错误消息
   * @param error 错误对象
   */
  static formatErrorMessage(error: any): string {
    if (typeof error === "string") {
      return error;
    }
    if (error?.response?.data?.message) {
      return error.response.data.message;
    }
    if (error?.message) {
      return error.message;
    }
    return "操作失败，请稍后重试";
  }

  /**
   * 检查是否需要登录
   * @param error 错误对象
   */
  static checkLoginRequired(error: any): boolean {
    if (error?.response?.status === 401) {
      return true;
    }
    if (error?.response?.data?.code === 401) {
      return true;
    }
    return false;
  }

  /**
   * 截取文本内容
   * @param content 文本内容
   * @param maxLength 最大长度
   */
  static truncateContent(content: string, maxLength: number = 100): string {
    if (!content) return "";
    if (content.length <= maxLength) return content;
    return content.substring(0, maxLength) + "...";
  }

  /**
   * 获取公告优先级排序值（用于排序）
   * 数值越小，优先级越高
   * @param announcement 公告对象
   */
  static getPriority(announcement: AnnouncementInfo): number {
    // 紧急 = 1, 重要 = 2, 普通 = 3
    const levelPriority = 4 - announcement.level;
    // 置顶的优先级更高
    const topPriority = announcement.isTop ? 0 : 1000;
    return topPriority + levelPriority;
  }

  /**
   * 对公告列表按优先级排序
   * @param announcements 公告列表
   */
  static sortByPriority(announcements: AnnouncementInfo[]): AnnouncementInfo[] {
    return [...announcements].sort((a, b) => {
      const priorityDiff = this.getPriority(a) - this.getPriority(b);
      if (priorityDiff !== 0) {
        return priorityDiff;
      }
      // 优先级相同时，按发布时间倒序
      return (
        new Date(b.publishTime).getTime() - new Date(a.publishTime).getTime()
      );
    });
  }

  /**
   * 获取公告级别的中文名称
   * @param level 级别值
   */
  static getLevelName(level: number): string {
    return this.getLevelInfo(level).label;
  }

  /**
   * 获取公告类型的中文名称
   * @param type 类型值
   */
  static getTypeName(type: number): string {
    return this.getTypeInfo(type).label;
  }

  /**
   * 生成公告详情URL
   * @param announcementId 公告ID
   */
  static generateAnnouncementUrl(announcementId: number): string {
    return `/user/announcement/${announcementId}`;
  }
}
